﻿using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Xml;
using System.Linq;
using System.Text;
using EventbriteService.Factory;
using EventbriteService.Util;

namespace EventbriteService.Adapter
{
   
    [CreateWithName(MessageFormat.XML)]
    public class XmlDocumentAdapter: IDataAdapter
    {
        private IEventBriteData _root;

        public XmlDocumentAdapter(string doc)
        {
            XDocument document = null;
            try
            {
                document = XDocument.Parse(doc);
            }
            catch (XmlException)
            {
                // remove illegal characters
                document = XDocument.Parse(CleanXml(doc));
            }

            _root = new Item(document.Root);
        }
       
        private string CleanXml(string doc)
        {
            StringBuilder buffer = new StringBuilder(doc.Length);
            foreach (char c in doc)
            {
                if (IsLegal(c))
                {
                    buffer.Append(c);
                }
            }
            return buffer.ToString();
        }

        private bool IsLegal(int c)
        {
            return (c == 0x9 || c == 0xA || c == 0xD ||
                    (c >= 0x20 && c <= 0xD7FF) ||
                    (c >= 0xE000 && c <= 0xFFFD) ||
                    (c >= 0x10000 && c <= 0x10FFFF)
                    );
        }
      
        #region IDataAdapter Members

        public IEventBriteData Root
        {
            get { return _root; }
        }

        #endregion

        public bool IsErrorMessage()
        {
            return _root.Name == "error";
        }
        
        private class Item : IEventBriteData
        {

            XElement _element;
            IEventBriteData[] _members;

            public Item(XElement element)
            {
                _element = element;
                _members = new IEventBriteData[_element.Elements().Count()];
                int counter = 0;
                foreach (var ele in _element.Elements())
                {
                    _members[counter++] = new Item(ele);
                }

            }
            
            #region IEventBriteData Members

            public IEnumerable<IEventBriteData> Elements()
            {
                return _members;
            }

            public string Name
            {
                get
                {
                    return _element.Name.LocalName;
                }
                set
                {
                    throw new NotImplementedException();
                }
            }

            public string Value
            {
                get
                {
                    return _element.Value;
                }
                set
                {
                    _element.Value = value;
                }
            }

            #endregion
        }
    }
}
